package com.googlecode.contests_repo.core;

import java.io.File;
import org.codehaus.jackson.map.ObjectMapper;
import com.googlecode.contests_repo.core.config.ConfigurationManager;
import com.googlecode.contests_repo.core.model.*;

/**
 * 
 * @author joro, petko
 * 
 */
public class WebTools {
	private static String resourceRegex = "[a-z0-9][a-z0-9_-]*";
	@SuppressWarnings("unused")
	private static String additionalFilesRegex = "_public_files|_files";

	/**
	 * 
	 * @author joro, petko
	 * 
	 */
	public enum ResourceType {
		/**
		 * 
		 */
		SERIES_LIST("seriesList"),
		/**
		 * 
		 */
		SERIES("series"),
		/**
		 * 
		 */
		CONTEST("contest"),
		/**
		 * 
		 */
		PROBLEM("problem"),
		/**
				 * 
				 */
		ADDITIONAL_FILE("view_folder");

		private String resourceTypeName;

		ResourceType(String resourceTypeName) {
			this.resourceTypeName = resourceTypeName;
		}

		/**
		 * 
		 * @return
		 * 		The resource type name
		 */
		public String getResourceTypeName() {
			return this.resourceTypeName;
		}

		/**
		 * 
		 * @return
		 * 		The successor type of this resource type
		 */
		public ResourceType getSuccessor() {
			switch (this) {
			case SERIES_LIST:
				return SERIES;
			case SERIES:
				return CONTEST;
			case CONTEST:
				return PROBLEM;
			case PROBLEM:
				return null;
			}

			return null;
		}
	}

	/**
	 * 
	 * @param path
	 * @return
	 * 		The resource type of a resource, given a full path to it
	 */
	public static ResourceType getResourceType(String path) {
		ResourceType[] results = { ResourceType.SERIES, ResourceType.CONTEST,
				ResourceType.PROBLEM };
		if (path.equals(ConfigurationManager.getInstance()
				.getSeriesRelativePath())) {
			return ResourceType.SERIES_LIST;
		}

		for (int i = 0; i < 3; i++) {
			path = path.substring(path.indexOf(File.separator) + 1);
			if (path.matches(resourceRegex)) {
				return results[i];
			} else if (path.startsWith("_public_files") || path.startsWith("_files")) {
				return ResourceType.ADDITIONAL_FILE;
			}
		}

		path = path.substring(path.indexOf(File.separator) + 1);
		if (path.startsWith("_public_files") || path.startsWith("_files")) {
			return ResourceType.ADDITIONAL_FILE;
		}
		return null;
	}

	/**
	 * 
	 * @param path
	 * @return
	 */
	public static String getResourceHandler(String path) {
		ResourceType resourceType = getResourceType(path);
		if (resourceType == null) {
			resourceType = ResourceType.SERIES_LIST;
		}
		return String.format("/%s.jsp", resourceType.getResourceTypeName());
	}

	/**
	 * 
	 * @param resourcePath
	 * @return
	 * 		Returns a path relative to the parent resource
	 */
	public static String getRelativeParentPath(String resourcePath) {
		return resourcePath.substring(0, resourcePath.lastIndexOf(File.separator));
	}

	private static String createJsonFile(ResourceType type, String resourcePath) {
		ObjectMapper mapper = new ObjectMapper();
		Resource resource = null;
		switch (type) {
		case SERIES:
			resource = new Series();
			break;
		case CONTEST:
			resource = new Contest();
			break;
		case PROBLEM:
			resource = new Problem();
			break;
		}
		try {
			mapper.writeValue(new File(resourcePath, type.getResourceTypeName()
					+ ".json"), resource);
		} catch (Exception e) {
			return "Unable to create json file";
		}
		return "";
	}

	/**
	 * 
	 * @param relativeParentPath
	 * @param resourceName
	 * @return
	 */
	public static String createEmptyResource(String relativeParentPath,
			String resourceName) {
		if (resourceName == null || resourceName.length() == 0) {
			return "The name of the new resource cannot be empty";
		}
		if (!resourceName.matches(resourceRegex)) {
			return "The name of the new resource is not valid";
		}
		String repoRoot = ConfigurationManager.getInstance().getRepoRoot();
		String newResourceDir = relativeParentPath + File.separator + resourceName;
		File resourceFile = new File(repoRoot + File.separator + newResourceDir);
		if (resourceFile.exists()) {
			return "A resource with that name already exists";
		}
		if (!resourceFile.mkdir()) {
			return "Unable to create resource";
		}
		return createJsonFile(getResourceType(newResourceDir), repoRoot + File.separator
				+ newResourceDir);
	}

	/**
	 * 
	 * @param color
	 * @param message
	 * @return
	 */
	public static String getFormatMessage(String color, String message) {
		return String.format("<div style='color:%s'>%s</div>", color, message);
	}
}
